package fudan.se.project.repository.entity.conference;

import fudan.se.project.domain.User;
import fudan.se.project.domain.conference.Conference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ConferenceRepository extends PagingAndSortingRepository<Conference, Long> {


    Conference findById(long id);

    //<editor-fold desc="admin">
    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state "
    )
    Page<Conference> findAllConferencesInPageByState(
            Conference.ConferenceState state,
            Pageable pageable
    );

    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state "
    )
    List<Conference> findAllConferencesByState(
            Conference.ConferenceState state,
            Sort sort
    );
    //</editor-fold>

    //<editor-fold desc="chair">
    @Query(value = "select " +
            "distinct conference " +
            "from Conference conference " +
            "where conference.chair.user=:user " +
            "and conference.state=:state"
    )
    Page<Conference> findConferencesAsChairInPageByState(
            User user, Conference.ConferenceState state,
            Pageable pageable
    );
    //</editor-fold>

    //<editor-fold desc="any">
    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state " +
            "and conference.stage=:stage " +
            "and ( " +
            "conference.chair.user=:user or " +
            "(:user in (select pcMember.user from conference.pcMembers pcMember)) or " +
            "(:user in (select author.user from conference.authors author)) " +
            ")"
    )
    Page<Conference> findConferencesAsAnyInPageByStateAndStage(
            User user,
            Conference.ConferenceState state,
            Conference.ConferenceStage stage,
            Pageable pageable
    );

    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state " +
            "and conference.stage<>:stage " +
            "and ( " +
            "conference.chair.user=:user or " +
            "(:user in (select pcMember.user from conference.pcMembers pcMember)) or " +
            "(:user in (select author.user from conference.authors author)) " +
            ")"
    )
    Page<Conference> findConferencesAsAnyInPageByStateAndNotStage(
            User user,
            Conference.ConferenceState state,
            Conference.ConferenceStage stage,
            Pageable pageable
    );
    //</editor-fold>

    //<editor-fold desc="all">

    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state " +
            "and conference.stage=:stage "
    )
    Page<Conference> findAllConferencesInPageByStateAndStage(
            Conference.ConferenceState state,
            Conference.ConferenceStage stage,
            Pageable pageable
    );

    @Query(value = "select " +
            "distinct conference from Conference conference " +
            "where  conference.state=:state " +
            "and conference.stage<>:stage "
    )
    Page<Conference> findAllConferencesInPageByStateAndNotStage(
            Conference.ConferenceState state,
            Conference.ConferenceStage stage,
            Pageable pageable
    );

    //</editor-fold>

}
